summaryrefslogtreecommitdiff
path: root/app/[lng]/evcp/(evcp)/evaluation/page.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'app/[lng]/evcp/(evcp)/evaluation/page.tsx')
-rw-r--r--app/[lng]/evcp/(evcp)/evaluation/page.tsx119
1 files changed, 84 insertions, 35 deletions
diff --git a/app/[lng]/evcp/(evcp)/evaluation/page.tsx b/app/[lng]/evcp/(evcp)/evaluation/page.tsx
index 4c498104..ae626e58 100644
--- a/app/[lng]/evcp/(evcp)/evaluation/page.tsx
+++ b/app/[lng]/evcp/(evcp)/evaluation/page.tsx
@@ -1,5 +1,5 @@
// ================================================================
-// 4. PERIODIC EVALUATIONS PAGE
+// 4. PERIODIC EVALUATIONS PAGE - 집계 뷰 지원 (정리된 버전)
// ================================================================
import * as React from "react"
@@ -8,7 +8,7 @@ import { type SearchParams } from "@/types/table"
import { getValidFilters } from "@/lib/data-table"
import { Shell } from "@/components/shell"
import { DataTableSkeleton } from "@/components/data-table/data-table-skeleton"
-import { HelpCircle } from "lucide-react"
+import { HelpCircle, BarChart3, List, Info } from "lucide-react"
import {
Popover,
PopoverContent,
@@ -16,10 +16,15 @@ import {
} from "@/components/ui/popover"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
+import { Alert, AlertDescription } from "@/components/ui/alert"
import { PeriodicEvaluationsTable } from "@/lib/evaluation/table/evaluation-table"
-import { getPeriodicEvaluations } from "@/lib/evaluation/service"
-import { searchParamsEvaluationsCache } from "@/lib/evaluation/validation"
+import { getPeriodicEvaluationsWithAggregation } from "@/lib/evaluation/service"
+import {
+ searchParamsEvaluationsCache,
+ type GetEvaluationsSchema
+} from "@/lib/evaluation/validation"
import { InformationButton } from "@/components/information/information-button"
+
export const metadata: Metadata = {
title: "협력업체 정기평가",
description: "협력업체 정기평가 진행 현황을 관리합니다.",
@@ -29,7 +34,7 @@ interface PeriodicEvaluationsPageProps {
searchParams: Promise<SearchParams>
}
-// 프로세스 안내 팝오버 컴포넌트
+// 프로세스 안내 팝오버 컴포넌트 - 집계 뷰 설명 포함
function ProcessGuidePopover() {
return (
<Popover>
@@ -46,6 +51,7 @@ function ProcessGuidePopover() {
확정된 평가 대상 업체들에 대한 정기평가 절차입니다.
</p>
</div>
+
<div className="space-y-3 text-sm">
<div className="flex gap-3">
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-blue-100 text-xs font-medium text-blue-600">
@@ -84,48 +90,68 @@ function ProcessGuidePopover() {
</div>
</div>
</div>
+
+ {/* 집계 뷰 설명 추가 */}
+ <div className="border-t pt-3 space-y-2">
+ <h5 className="font-medium text-sm flex items-center gap-1">
+ <Info className="h-3 w-3" />
+ 보기 모드
+ </h5>
+ <div className="space-y-2 text-xs">
+ <div className="flex items-center gap-2">
+ <List className="h-3 w-3 text-blue-600" />
+ <span className="font-medium">상세 뷰:</span>
+ <span className="text-muted-foreground">모든 평가 기록을 개별적으로 표시</span>
+ </div>
+ <div className="flex items-center gap-2">
+ <BarChart3 className="h-3 w-3 text-purple-600" />
+ <span className="font-medium">집계 뷰:</span>
+ <span className="text-muted-foreground">동일 벤더의 여러 division 평가를 평균으로 통합</span>
+ </div>
+ </div>
+ </div>
</div>
</PopoverContent>
</Popover>
)
}
-// TODO: 이 함수들은 실제 서비스 파일에서 구현해야 함
-function getDefaultEvaluationYear() {
- return new Date().getFullYear()
+// 집계 모드 안내 컴포넌트
+function AggregatedModeNotice({ isAggregated }: { isAggregated: boolean }) {
+ if (!isAggregated) return null;
+
+ return (
+ <Alert className="mb-4 border-purple-200 bg-purple-50">
+ <BarChart3 className="h-4 w-4 text-purple-600" />
+ <AlertDescription className="text-purple-800">
+ 현재 <strong>집계 뷰</strong>로 표시되고 있습니다.
+ 동일 벤더의 여러 division 평가 결과가 평균으로 통합되어 표시됩니다.
+ </AlertDescription>
+ </Alert>
+ );
}
-
-
export default async function PeriodicEvaluationsPage(props: PeriodicEvaluationsPageProps) {
const searchParams = await props.searchParams
+
+ // ✅ nuqs 기반 파라미터 파싱
const search = searchParamsEvaluationsCache.parse(searchParams)
const validFilters = getValidFilters(search.filters || [])
- // 기본 필터 처리
- let basicFilters = []
- if (search.basicFilters && search.basicFilters.length > 0) {
- basicFilters = search.basicFilters
- }
-
- // 모든 필터를 합쳐서 처리
- const allFilters = [...validFilters, ...basicFilters]
-
- // 조인 연산자
- const joinOperator = search.basicJoinOperator || search.joinOperator || 'and';
-
// 현재 평가년도
- const currentEvaluationYear = search.evaluationYear || getDefaultEvaluationYear()
+ const currentEvaluationYear = search.evaluationYear
- // Promise.all로 감싸서 전달
+ // ✅ 집계 모드를 지원하는 서비스 함수 사용
const promises = Promise.all([
- getPeriodicEvaluations({
+ getPeriodicEvaluationsWithAggregation({
...search,
- filters: allFilters,
- joinOperator,
+ filters: validFilters,
})
])
+ // ✅ 현재 모드 표시용 변수
+ const currentMode = search.aggregated ? "집계" : "상세"
+
return (
<Shell className="gap-4">
{/* 헤더 */}
@@ -137,27 +163,47 @@ export default async function PeriodicEvaluationsPage(props: PeriodicEvaluations
협력업체 정기평가
</h2>
<InformationButton pagePath="evcp/evaluation" />
+ {/* <ProcessGuidePopover /> */}
+ </div>
+ <div className="flex items-center gap-2">
+ <Badge variant="outline" className="text-sm">
+ {currentEvaluationYear}년도
+ </Badge>
+ {/* ✅ 현재 보기 모드 표시 */}
+ <Badge
+ variant={search.aggregated ? "default" : "secondary"}
+ className={`text-xs ${search.aggregated ? 'bg-purple-600' : ''}`}
+ >
+ <div className="flex items-center gap-1">
+ {search.aggregated ? (
+ <BarChart3 className="h-3 w-3" />
+ ) : (
+ <List className="h-3 w-3" />
+ )}
+ {currentMode} 뷰
+ </div>
+ </Badge>
</div>
- <Badge variant="outline" className="text-sm">
- {currentEvaluationYear}년도
- </Badge>
</div>
</div>
</div>
+
+ {/* ✅ 집계 모드 안내 */}
+ <AggregatedModeNotice isAggregated={search.aggregated} />
{/* 메인 테이블 */}
<React.Suspense
- key={JSON.stringify(searchParams)}
+ key={JSON.stringify(searchParams)} // 집계 모드 변경 시에도 리렌더링
fallback={
<DataTableSkeleton
- columnCount={15}
+ columnCount={search.aggregated ? 17 : 15} // 집계 모드에서 컬럼 추가
searchableColumnCount={2}
filterableColumnCount={8}
cellWidths={[
"3rem", // checkbox
"5rem", // 평가년도
- "5rem", // 평가기간
- "4rem", // 구분
+ "5rem", // 평가기간 or 평가수 (집계 모드)
+ "6rem", // 구분 (집계 모드에서 더 넓게)
"8rem", // 벤더코드
"12rem", // 벤더명
"4rem", // 내외자
@@ -168,7 +214,8 @@ export default async function PeriodicEvaluationsPage(props: PeriodicEvaluations
"4rem", // 총점
"4rem", // 등급
"5rem", // 진행상태
- "8rem" // actions
+ "8rem", // actions
+ ...(search.aggregated ? ["5rem", "5rem"] : []) // 집계 모드 추가 컬럼
]}
shrinkZero
/>
@@ -177,6 +224,8 @@ export default async function PeriodicEvaluationsPage(props: PeriodicEvaluations
<PeriodicEvaluationsTable
promises={promises}
evaluationYear={currentEvaluationYear}
+ // ✅ 현재 뷰 모드를 테이블 컴포넌트에 전달
+ initialViewMode={search.aggregated ? "aggregated" : "detailed"}
/>
</React.Suspense>
</Shell>